import { initPhysics } from './game-physics'
import { generateTerrain } from './terrain-generator'
import EffectManager from './effect-manager'

// 轨迹着色器
const trailVertexShader = `
  attribute vec3 position;
  attribute float alpha;
  uniform mat4 modelViewMatrix;
  uniform mat4 projectionMatrix;
  varying float vAlpha;
  
  void main() {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    vAlpha = alpha;
  }
`

const trailFragmentShader = `
  precision mediump float;
  varying float vAlpha;
  uniform vec3 color;
  
  void main() {
    gl_FragColor = vec4(color, vAlpha);
  }
`

// 音效管理器
class SoundManager {
  constructor() {
    this.sounds = {}
    this.context = new (window.AudioContext || window.webkitAudioContext)()
  }

  async load(name, url) {
    const response = await fetch(url)
    const arrayBuffer = await response.arrayBuffer()
    const audioBuffer = await this.context.decodeAudioData(arrayBuffer)
    this.sounds[name] = audioBuffer
  }

  play(name, volume = 1.0) {
    if (!this.sounds[name]) return
    
    const source = this.context.createBufferSource()
    source.buffer = this.sounds[name]
    
    const gainNode = this.context.createGain()
    gainNode.gain.value = volume
    
    source.connect(gainNode)
    gainNode.connect(this.context.destination)
    source.start(0)
  }
}

export function initGameScene(canvas, options = {}) {
  // 初始化WebGL上下文
  const gl = canvas.getContext('webgl', {
    antialias: true,
    alpha: false
  })

  // 初始化音效
  const soundManager = new SoundManager()
  soundManager.load('collision', './static/sounds/collision.wav')
  soundManager.load('rolling', './static/sounds/rolling.wav')
  soundManager.load('goal', './static/sounds/goal.wav')
  
  if (!gl) {
    console.error('无法获取WebGL上下文')
    return null
  }

  // 编译轨迹着色器
  function compileShader(source, type) {
    const shader = gl.createShader(type)
    gl.shaderSource(shader, source)
    gl.compileShader(shader)
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      console.error('着色器编译错误:', gl.getShaderInfoLog(shader))
      return null
    }
    return shader
  }

  const trailProgram = gl.createProgram()
  gl.attachShader(trailProgram, compileShader(trailVertexShader, gl.VERTEX_SHADER))
  gl.attachShader(trailProgram, compileShader(trailFragmentShader, gl.FRAGMENT_SHADER))
  gl.linkProgram(trailProgram)

  // 场景状态
  const state = {
    gl,
    trailProgram,
    camera: {
      angle: options.cameraAngle || 30,
      distance: 1000,
      target: [0, 0, 0]
    },
    terrain: null,
    marbles: [],
    lastFrameTime: 0,
    effectManager: null
  }

  // 初始化物理引擎
  state.physics = initPhysics()

  // 生成地形
  state.terrain = generateTerrain({
    type: options.terrainType || 'grassland',
    size: 2000
  })

  // 初始化特效管理器
  state.effectManager = new EffectManager(state)

  // 渲染循环
  function render(timestamp) {
    const deltaTime = timestamp - state.lastFrameTime
    state.lastFrameTime = timestamp

    // 清除画布
    gl.clearColor(0.1, 0.2, 0.3, 1.0)
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

    // 更新物理模拟
    state.physics.update(deltaTime)

    // 更新特效
    state.effectManager.update(deltaTime)

    // 设置摄像机矩阵
    const cameraMatrix = calculateCameraMatrix(state.camera)

    // 渲染地形
    renderTerrain(gl, state.terrain, cameraMatrix)

    // 更新并渲染弹珠
    state.marbles.forEach(marble => {
      updateMarbleTrail(marble)
      renderMarble(gl, marble, cameraMatrix)
    })

    requestAnimationFrame(render)
  }

  // 启动渲染循环
  requestAnimationFrame(render)

  return {
    updateState(newState) {
      // 更新游戏状态
      state.marbles = newState.marbles
    },
    dispose() {
      // 清理资源
      state.physics.dispose()
      state.effectManager.clear()
    }
  }
}

function calculateCameraMatrix(camera) {
  // 计算30度俯视角的视图矩阵
  // 实现细节...
}

function renderTerrain(gl, terrain, cameraMatrix) {
  // 地形渲染实现
  // 实现细节...
}

function renderMarble(gl, marble, cameraMatrix) {
  // 弹珠渲染实现
  // 实现细节...

  // 渲染轨迹
  if (marble.trailPoints && marble.trailPoints.length > 1) {
    const trailProgram = gl.trailProgram
    gl.useProgram(trailProgram)
    
    // 创建轨迹顶点缓冲区
    const positions = []
    const alphas = []
    const maxPoints = 50 // 最大轨迹点数
    const startIdx = Math.max(0, marble.trailPoints.length - maxPoints)
    
    for (let i = startIdx; i < marble.trailPoints.length; i++) {
      const point = marble.trailPoints[i]
      positions.push(point.position[0], point.position[1], point.position[2])
      
      // 计算透明度 (越新的点越透明)
      const age = (Date.now() - point.timestamp) / 1000
      alphas.push(Math.max(0, 1 - age / 2))
    }

    // 设置顶点属性
    const positionBuffer = gl.createBuffer()
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
    
    const positionLoc = gl.getAttribLocation(trailProgram, 'position')
    gl.enableVertexAttribArray(positionLoc)
    gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0)
    
    const alphaBuffer = gl.createBuffer()
    gl.bindBuffer(gl.ARRAY_BUFFER, alphaBuffer)
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(alphas), gl.STATIC_DRAW)
    
    const alphaLoc = gl.getAttribLocation(trailProgram, 'alpha')
    gl.enableVertexAttribArray(alphaLoc)
    gl.vertexAttribPointer(alphaLoc, 1, gl.FLOAT, false, 0, 0)
    
    // 设置统一变量
    const colorLoc = gl.getUniformLocation(trailProgram, 'color')
    gl.uniform3f(colorLoc, marble.color[0], marble.color[1], marble.color[2])
    
    // 绘制轨迹线
    gl.drawArrays(gl.LINE_STRIP, 0, positions.length / 3)
    
    // 清理
    gl.deleteBuffer(positionBuffer)
    gl.deleteBuffer(alphaBuffer)
  }
}

// 更新弹珠轨迹点
function updateMarbleTrail(marble) {
  if (!marble.trailPoints) {
    marble.trailPoints = []
  }
  
  const now = Date.now()
  const lastPoint = marble.trailPoints[marble.trailPoints.length - 1]
  
  // 根据速度调整采样频率
  const speed = Math.sqrt(
    marble.velocity[0] * marble.velocity[0] +
    marble.velocity[1] * marble.velocity[1] +
    marble.velocity[2] * marble.velocity[2]
  )
  
  const minInterval = 100 // 毫秒
  const maxInterval = 500 // 毫秒
  const interval = Math.max(minInterval, maxInterval - speed * 10)
  
  if (!lastPoint || now - lastPoint.timestamp > interval) {
    marble.trailPoints.push({
      position: [...marble.position],
      timestamp: now
    })
  }
  
  // 移除过旧的轨迹点
  const maxAge = 2000 // 毫秒
  marble.trailPoints = marble.trailPoints.filter(
    p => now - p.timestamp < maxAge
  )
}
